﻿using Jint;
using Jint.Native;
using Microsoft.Extensions.Caching.Distributed;
using Microsoft.Extensions.Caching.StackExchangeRedis;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using StackExchange.Redis;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Dynamic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;

namespace CK.Sprite.Core
{
    public class RedisSerialNumberService : ISerialNumberService
    {
        private readonly RedisCache _redisCache;
        public RedisSerialNumberService(IDistributedCache redisCache)
        {
            _redisCache = (RedisCache)redisCache;
        }

        /// <summary>
        /// Redis生成流水号
        /// </summary>
        /// <param name="serialNumberInfo">流水号信息</param>
        /// <param name="redisKey">格式：表名-字段名称</param>
        /// <param name="length">生成多少个流水号，默认为1</param>
        /// <returns>注意：生成的流水号数组是按照从大到小排序的</returns>
        public async Task<List<string>> CreateSerialNumber(SerialNumberInfo serialNumberInfo, string redisKey, int length = 1)
        {
            List<string> results = new List<string>();
            string serialNumberKey = "";
            long maxNumber = 0;
            var dataBase = _redisCache.GetDatabaseAsync().Result;
            if (serialNumberInfo.useDay)
            {
                serialNumberKey = $"{serialNumberInfo.preNo}{DateTime.Now.ToString("yyyyMMdd")}";
                redisKey = $"{redisKey}{DateTime.Now.ToString("yyyyMMdd")}";
                await dataBase.KeyExpireAsync(redisKey, TimeSpan.FromDays(2));
                maxNumber = await dataBase.StringIncrementAsync(redisKey, length);
            }
            else if (serialNumberInfo.useMonth)
            {
                serialNumberKey = $"{serialNumberInfo.preNo}{DateTime.Now.ToString("yyyyMM")}";
                redisKey = $"{redisKey}{DateTime.Now.ToString("yyyyMM")}";
                await dataBase.KeyExpireAsync(redisKey, TimeSpan.FromDays(32));
                maxNumber = await dataBase.StringIncrementAsync(redisKey, length);
            }
            else if (serialNumberInfo.useYear)
            {
                serialNumberKey = $"{serialNumberInfo.preNo}{DateTime.Now.ToString("yyyy")}";
                redisKey = $"{redisKey}{DateTime.Now.ToString("yyyy")}";
                await dataBase.KeyExpireAsync(redisKey, TimeSpan.FromDays(368));
                maxNumber = await dataBase.StringIncrementAsync(redisKey, length);
            }
            else
            {
                serialNumberKey = $"{serialNumberInfo.preNo}";
                maxNumber = await dataBase.StringIncrementAsync(redisKey, length);
            }
            for (var i = 0; i <= length; i++)
            {
                results.Add($"{serialNumberKey}{maxNumber.ToString().PadLeft(serialNumberInfo.length, '0')}");
            }

            return results;
        }
    }
}
